//
// Copyright (c) 2009-2011, chunquedong
//
// This file is part of ChunMap project
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
//
// History:
//   2011-11-30  Jed Young  Creation
//

using chunmapData
using chunmapModel
using slanActor

**
** FeatureSet from readonly database
**
class DataFeatureSet : FeatureSet
{
  Cache cache
  DataReader reader
  QuartTreeIndex index

  new make(|This| f) : super.make(f) {}

  override This add(Feature f) { throw UnsupportedErr() }
  override Feature? remove(Feature f) { throw UnsupportedErr() }

  override Void each(Condition condition, |Feature| filter)
  {
    if (condition.envelope == null) throw UnsupportedErr()
    keys := index.findKeys(condition.envelope)
    keys.each |skey|
    {
      dataUnit := getData(skey)
      dataUnit.features.each |Feature f|
      {
        if (condition.envelope == null || condition.envelope.intersects(f.envelope))
        {
          filter(f)
        }
      }
    }
  }

  private DataUnit getData(Str skey)
  {
    obj := cache.get(skey)
    if (obj == null)
    {
      obj = reader.find(skey)
      cache.set(skey, obj)
    }
    return obj
  }

  override Feature? find(Condition condition, |Feature->Bool| filter)
  {
    if (condition.envelope == null) throw UnsupportedErr()
    keys := index.findKeys(envelope)

    Feature? result := null
    keys.find |skey|
    {
      dataUnit := getData(skey)
      result = dataUnit.features.find |Feature f->Bool|
      {
        if (condition.envelope == null || condition.envelope.intersects(f.envelope))
        {
          return filter(f)
        }
        return false
      }
      return (result != null)
    }
    return result
  }
}